package apache.openejb.session.bean.stateful.client;

import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Properties;

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.rmi.PortableRemoteObject;

import apache.openejb.session.bean.stateful.AccountRemote;

public class AccountRemoteClient implements Runnable {
    
    public void run() {        
        Properties props = new Properties();
        props.put(Context.INITIAL_CONTEXT_FACTORY, "org.apache.openejb.client.RemoteInitialContextFactory");
        //different vm in different machine
        props.put(Context.PROVIDER_URL, "http://192.168.1.252:8080/tomee/ejb");
        //different vm in same machine
        //props.put(Context.PROVIDER_URL, "http://localhost:8080/tomee/ejb");

        try {
            
            Context ctx = new InitialContext(props);
            Object ref = ctx.lookup("AccountImplRemote");
            AccountRemote r = (AccountRemote)PortableRemoteObject.narrow(ref, AccountRemote.class);
            
            String hostname = InetAddress.getLocalHost().getHostName();
            String result="";
            
            for (int i=0; i<2; i++) {
                r.deposit(1000);
                result = r.result(Thread.currentThread().getName() + " call deposit(1000) is called at " + hostname);
                System.out.println(result);  
            }
            
        } catch (NamingException e) {
            e.printStackTrace();
        } catch (UnknownHostException e) {
            e.printStackTrace();
        }
    }
    
    public static void main(String[] args) throws Exception{
        AccountRemoteClient c = new AccountRemoteClient();
        for(int i=0 ; i<5; i++) {
            Thread t = new Thread(c, "T" + i);
            t.start();
        }
        
        /*
            For a stateless session bean, if a thread call the deposit(1000) method 2 times, it is not guaranteed that you'll get 2000 per thread. 
            It is up to the container which EJB it'll assign to your call. 
            So if you are assigned a new EJB instance, then you'll get a zero. 
            It is also possible that the container has not cleaned up your EJB instance, so it might be possible to get a 2000 -- but it is not guaranteed.
             
            T0 call deposit(1000) is called at i3300, and balance is 2000.0 at EWINXP1
            T2 call deposit(1000) is called at i3300, and balance is 1000.0 at EWINXP1
            T4 call deposit(1000) is called at i3300, and balance is 0.0 at EWINXP1
            T1 call deposit(1000) is called at i3300, and balance is 0.0 at EWINXP1
            T3 call deposit(1000) is called at i3300, and balance is 2000.0 at EWINXP1
            T3 call deposit(1000) is called at i3300, and balance is 0.0 at EWINXP1
            T4 call deposit(1000) is called at i3300, and balance is 3000.0 at EWINXP1
            T1 call deposit(1000) is called at i3300, and balance is 4000.0 at EWINXP1
            T2 call deposit(1000) is called at i3300, and balance is 1000.0 at EWINXP1
            T0 call deposit(1000) is called at i3300, and balance is 2000.0 at EWINXP1

             
             
            For a stateful session bean, if you call the deposit(1000) method 5times, you'll get a 2000 per thread
            The container guarantees that the EJB that was used the first time you called will be used for all subsequent calls.
            
            T2 call deposit(1000) is called at i3300, and balance is 1000.0 at EWINXP1
            T3 call deposit(1000) is called at i3300, and balance is 1000.0 at EWINXP1
            T4 call deposit(1000) is called at i3300, and balance is 1000.0 at EWINXP1
            T0 call deposit(1000) is called at i3300, and balance is 1000.0 at EWINXP1
            T1 call deposit(1000) is called at i3300, and balance is 1000.0 at EWINXP1
            T3 call deposit(1000) is called at i3300, and balance is 2000.0 at EWINXP1
            T2 call deposit(1000) is called at i3300, and balance is 2000.0 at EWINXP1
            T0 call deposit(1000) is called at i3300, and balance is 2000.0 at EWINXP1
            T4 call deposit(1000) is called at i3300, and balance is 2000.0 at EWINXP1
            T1 call deposit(1000) is called at i3300, and balance is 2000.0 at EWINXP1
         */        
    }
}